package stateorder

import (
	"fmt"
	"time"
)

// OrderState 抽象状态接口订单
type OrderState interface {
	// Pay 支付
	Pay(order *Order) error
	// Cancel 取消
	Cancel(order *Order) error
	// Ship 发货
	Ship(order *Order) error
	// Deliver 发货
	Deliver(order *Order) error
	GetName() string
}

// NoPay 未支付状态
type NoPay struct {
}

// Pay 支付
func (n *NoPay) Pay(order *Order) error {
	return fmt.Errorf("订单 %s %s，无需重复支付", order.ID,  order.State.GetName())
}

// NoCancel 不能取消
type NoCancel struct {
}

// Cancel 取消
func (n *NoCancel) Cancel(order *Order) error {
	return fmt.Errorf("订单 %s %s，无法取消", order.ID, order.State.GetName())
}

// NoShip 未发货状态
type NoShip struct {
}

// Ship 发货
func (n *NoShip) Ship(order *Order) error {
	return fmt.Errorf("订单 %s %s，无法发货", order.ID, order.State.GetName())
}

// NoDeliver 未发货状态
type NoDeliver struct {
}

// Deliver 发货
func (n *NoDeliver) Deliver(order *Order) error {
	return fmt.Errorf("订单 %s %s，无法标记为已送达", order.ID, order.State.GetName())
}

// PendingState 待支付状态
type PendingState struct {
	NoShip
	NoDeliver
}

// Pay 支付
func (p *PendingState) Pay(order *Order) error {
	fmt.Printf("处理订单 %s 的支付...\n", order.ID)
	// 模拟支付处理
	fmt.Printf("¥%.2f 支付成功!\n", order.TotalAmount)
	order.TransitionTo(&PaidState{})
	return nil
}

// Cancel 取消
func (p *PendingState) Cancel(order *Order) error {
	fmt.Printf("处理订单 %s 的取消...\n", order.ID)
	order.TransitionTo(&CancelState{})
	return nil
}

func (p *PendingState) GetName() string {
	return "待支付"
}

// PaidState 已支付状态
type PaidState struct {
	NoPay
	NoDeliver
}

// Cancel 取消
func (p *PaidState) Cancel(order *Order) error {
	fmt.Printf("取消订单 %s，退款处理中...\n", order.ID)
	fmt.Printf("¥%.2f 已退回原支付账户\n", order.TotalAmount)
	order.TransitionTo(&CancelState{})
	return nil
}

// Ship 发货
func (p *PaidState) Ship(order *Order) error {
	fmt.Printf("订单 %s 已发货\n", order.ID)
	order.ShippedAt = time.Now()
	order.TransitionTo(&ShippedState{})
	return nil
}

func (p *PaidState) GetName() string {
	return "已支付"
}

// ShippedState 已发货状态
type ShippedState struct {
	NoPay
	NoCancel
	NoShip
}

// Deliver 发货
func (s *ShippedState) Deliver(order *Order) error {
	fmt.Printf("订单 %s 已标记为已送达\n", order.ID)
	order.DeliveredAt = time.Now()
	order.TransitionTo(&DeliveredState{})
	return nil
}

// GetName 已发货
func (s *ShippedState) GetName() string {
	return "已发货"
}

// DeliveredState 已送达状态
type DeliveredState struct {
	NoPay
	NoCancel
	NoShip
	NoDeliver
}

// GetName 已送达
func (d *DeliveredState) GetName() string {
	return "已送达"
}

// CancelState 已取消状态
type CancelState struct {
	NoPay
	NoCancel
	NoShip
	NoDeliver
}

func (c *CancelState) GetName() string {
	return "已取消"
}
